package org.tang.springcloudvv.interceptor;

import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.tang.springcloudvv.util.SqlUtil;

import java.util.Properties;

/**
 * tangfuzhong
 * mybatis插件，把sqlId关联到慢sql记录
 * 使用方法1.需要在mybatis-config.xml配置本插件MybatisSqlInterceptor
 * 使用方法2.通过PluginHelper自动注入插件MybatisSqlInterceptor到容器中
 */

@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
             @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class,BoundSql.class})}
)
public class MybatisSqlInterceptor implements Interceptor {
    static int MAPPED_STATEMENT_INDEX = 0;

    @Autowired
    private Configuration configuration;

    @Override
    public Object intercept(final Invocation invocation) throws Throwable {
        Object[] queryArgs = invocation.getArgs();
        MappedStatement ms = (MappedStatement)queryArgs[MAPPED_STATEMENT_INDEX];
        BoundSql boundSql = ms.getBoundSql(queryArgs[1]);
        Configuration configuration = ms.getConfiguration();
        //String sql = boundSql.getSql();
        String sql = SqlParamDeal.showSql(configuration,boundSql );

        long startTime = System.currentTimeMillis();
        Object val = invocation.proceed();
        long useTime = System.currentTimeMillis() - startTime;
        SqlUtil.checkSlowSql(sql,useTime,ms.getId());

        return val;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
